/*
    Copyright 2010 Northbranchlogic, Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

package com.norbl.runjrun;

import java.io.*;
import java.util.*;
import com.norbl.util.*;
import com.xerox.amazonws.ec2.*;

/** This app is used to programmatically launch {@link RunnerNodeEc2} using
 * `<tt>java.lang.ProcessBuilder</tt>.  We this use this class (rather
 *  than a shell script), because it allows us to get the Java Runtime
 *  params from the Ec2 instance user data.
 *
 * @author Barnet Wagman
 */
public class RunnerNodeEc2Launcher {

    public static String JVM_PN = "jvm";
    public static String WORKING_DIR_PN = "workingDir";
    public static String CP_PN = "cp";

    public static int MAX_HEAP_GB_DEFAULT = 7;

    public static void main(String[] argv) {
        new RunnerNodeEc2Launcher(argv);
    }

    public RunnerNodeEc2Launcher(String[] argv) {
        try {           
            ArgvHt argvHt = new ArgvHt(argv);

            String jvm = argvHt.get(JVM_PN);
            if ( jvm == null )
                throw new RunJRunException("The jvm path is not " +
                                            " in argv[].");

            String classpath = argvHt.get(CP_PN);
            if ( classpath == null )
                throw new RunJRunException("The cp is null in argv[].");

            String workingDirString = argvHt.get(WORKING_DIR_PN);
            if ( workingDirString == null )
                throw new RunJRunException("The workingDir is not in argv[].");

            File workingDir = new File(workingDirString);
            if ( !workingDir.exists() || !workingDir.isDirectory() )
                throw new RunJRunException("Working dir " +
                    workingDir.getPath() + " does not exist or is not a dir.");

            
            NodeParams params = new NodeParams(getUserData());
            
            String jvmParams = null;

            if ( (params.jvmParams != null) && (params.jvmParams.length() > 1) ) {
                if ( hasMaxHeapSetting(params.jvmParams) ) { // ignore the maxHeap param
                    jvmParams = params.jvmParams;
                }
                else {
                    int maxHeapGb = params.maxHeapGb.intValue();
                    if ( maxHeapGb < 1 ) maxHeapGb = MAX_HEAP_GB_DEFAULT;
                    jvmParams = " -Xmx" + Integer.toString(maxHeapGb) + "g " +
                            params.jvmParams;
                }
            }
            else {
                int maxHeapGb = params.maxHeapGb.intValue();
                if ( maxHeapGb < 1 ) maxHeapGb = MAX_HEAP_GB_DEFAULT;
                jvmParams = " -Xmx" + Integer.toString(maxHeapGb) + "g " +
                            Constants.NODE_JVM_PARAMS_DEFAULT;
            }

            launch(jvm,jvmParams,workingDir,classpath);
            
        }
        catch(Throwable xxx) {
            System.out.println(StringUtil.throwableToString(xxx));
            System.exit(0);
        }
    }


    public void launch(String javaRuntimePath,
                       String jrtParams, File workingDir,
                       String classpath) throws IOException {

        List<String> com = new ArrayList<String>();

        com.add(javaRuntimePath);
        com.add(jrtParams);
        com.add(" -classpath " + classpath + " ");
        com.add(RunnerNodeEc2.class.getName());

        String command = javaRuntimePath + " " + jrtParams + " " +
                         " -classpath " + classpath + " " +
                         RunnerNodeEc2.class.getName();

        Process p = Runtime.getRuntime().exec(command,null,workingDir);
    }

    protected String getUserData() {
        try {
            return( EC2Utils.getInstanceUserdata() );
        }
        catch(Exception x) { throw new RunJRunException(x); }
    }

    boolean hasMaxHeapSetting(String s) {
        return( s.contains("-Xmx") && (s.length() > 4) );
    }
}
